/*
 	Keycounter.h

 	Copyright (c) 2008 Bojan Rajkovic

 	Permission is hereby granted, free of charge, to any person obtaining a copy
 	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
 	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 	copies of the Software, and to permit persons to whom the Software is
 	furnished to do so, subject to the following conditions:
	
 	The above copyright notice and this permission notice shall be included in
 	all copies or substantial portions of the Software.

 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 	THE SOFTWARE.
*/
// we only want the header included once, probably should use conditional includes
// but #pragma once is actually the same across all compilers
#pragma once

// include definitions from pulse and utility classes so we can use those functions
#include "Pulse.h"
#include "Utility.h"
#include "AllPurpose.h"
// various system headers that we need in the main loop
#include <linux/input.h>
#include <sys/sysinfo.h>
#include <sys/un.h>
#include <fcntl.h>
#include <pwd.h>
#include <getopt.h>
#include <fcntl.h>
	 	  
namespace LinPulse {
	
		class KeycounterException {
			
			private:
				std::string error;
				
			public:
			
				KeycounterException(std::string Error) {
					this->error = Error;
					Utility::LogMessage(Utility::FormatString("KeycounterException: %s", what()), M_ERROR);
				}
			
				virtual const char* what() const throw() {
					return this->error.c_str();	
				}
		};
	
		class Keycounter {
			
			private:
				
				std::ifstream eventReader;
				std::ofstream outputWriter;
				unsigned long keys, sessionKeys;
				bool dying, verboseOutput;
				time_t lastPulse, startupTime;
				std::string configFile;
				
			public:
			
				// Parameterless constructor
				Keycounter();
				// Constructor with parameters for eventDevice and outputFile
				Keycounter(std::string, std::string, std::string);
				// Destructor
				~Keycounter() {
					Utility::LogMessage("Destroying Keycounter.", M_INFO);
					this->eventReader.close();
					this->outputWriter.close();
				}
				// Open the keycounter
				void Open(std::string, std::string);
				// Run the keycounter. This is where our infinite loop goes.
				void Run();
				// Send the pulse
				bool Pulse();
				// Get a configuration setting
				libconfig::Setting GetSetting(std::string);
				// Get the number of keys since the last pulse
				inline unsigned long Keys() {
					return keys;
				}
				// Get the number of keys in this session
				inline unsigned long SessionKeys() {
					return this->sessionKeys;
				}
				// Get the system uptime, in minutes.
				inline float SystemUptime() {
					// Get lots of system info, pull out the uptime
					struct sysinfo systemInfo;
					sysinfo(&systemInfo);
					float uptime = systemInfo.uptime/60;
					return uptime;
				}
				// Get the program uptime
				inline float ProgramUptime() {
					// Instead of using clock() to get our own uptime, we'll just subtract 2 time_t's -- now, and when we started
					// clock() gives us CPU time, not real time, which is totally useless
					return (time(NULL) - this->startupTime)/60;
				}
				// Get the time since the last pulse, in minutes
				inline float TimeSinceLastPulse() {
					return (time(NULL) - this->lastPulse)/60;
				}
				
				void LoadPulseFile();
		};
		
}

using namespace LinPulse;
